package com.gingko.duominuo.viewmodel

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.gingko.duominuo.network.exception.*
import com.gingko.duominuo.utils.logi
import com.google.gson.JsonParseException
import com.google.gson.stream.MalformedJsonException
import event.SingleLiveEvent
import kotlinx.coroutines.*
import org.json.JSONException
import retrofit2.HttpException
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException
import java.text.ParseException
import java.util.concurrent.TimeoutException

open class BaseViewModel : ViewModel() {
    protected val _loadingLiveData by lazy { MutableLiveData<Boolean>() }
    val loadingLiveData: LiveData<Boolean> = _loadingLiveData;

    //运行在UI线程的协程
    fun launchOnUI(
        task: suspend CoroutineScope.() -> Unit,
        onFailure: (e: Exception) -> Unit = {},
        onComplete: () -> Unit = {},
        isShowLoading: Boolean = true
    ) = viewModelScope.launch(Dispatchers.Main) {
        if (isShowLoading) {
            "onStart".logi("------------>")
            _loadingLiveData.value = true
        }
        try {
            task()
        } catch (e: Exception) {
            e.printStackTrace()
            onFailure(e)
        } finally {
            if (isShowLoading) {
                "onComplete".logi("------------>")
                _loadingLiveData.value = false
            }
            onComplete()
        }
    }


    //运行在IO线程的协程
    protected fun launchOnIO(
        task: suspend CoroutineScope.() -> Unit,
        onFailure: (e: Exception) -> Unit = {},
        onComplete: () -> Unit = {},
        isShowLoading: Boolean = true
    ) = viewModelScope.launch(Dispatchers.IO) {
        if (isShowLoading) {
            _loadingLiveData.postValue(true)
        }
        try {
            task()
        } catch (e: Exception) {
            e.printStackTrace()
            onFailure(e)
        } finally {
            if (isShowLoading) {
                _loadingLiveData.postValue(false)
            }
            onComplete()
        }
    }

    private fun handlerApiException(e: Throwable): NativeException {
        return if (e is HttpException) {
            /*网络异常*/
            NativeException(HTTP_ERROR, "网络异常，请稍后重试")
        } else if (e is ConnectException) {
            /*链接异常*/
            NativeException(CONNECT_ERROR, "请求失败，请检查网络后重试")
        } else if (e is SocketTimeoutException || e is TimeoutException) {
            /*请求超时异常*/
            NativeException(TIME_OUT_ERROR, "请求超时，请稍后重试")
        } else if (e is JsonParseException || e is JSONException
            || e is ParseException || e is MalformedJsonException
        ) {
            NativeException(PARSE_ERROR, "数据解析失败")
        } else if (e is UnknownHostException) {
            /*无法解析该域名异常*/
            NativeException(UNKNOWN_HOST_ERROR, "网络无连接，请检查网络后重试")
        } else {
            /*未知异常*/
            NativeException(UNKNOWN_ERROR, "网络异常，请稍后重试")
        }
    }
}